﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using Core.Entities;
using Core.Reader;
using Core.Writer;

namespace Core.CommandProcesser
{
    public abstract class BaseCommandProcesser
    {
        /// <summary> 匹配程序集导入 </summary>
        private static readonly Regex ImportRegex;
        /// <summary> 匹配命名空间引入 </summary>
        private static readonly Regex UsingRegex;
        /// <summary> 匹配参数验证器 </summary>
        private static readonly Regex ValidationRegex;

        static BaseCommandProcesser()
        {
            /* 匹配 Name = Value Description */
            ValidationRegex = new Regex("^// *valid *(?<Name>[A-Za-z_]+[A-Za-z0-9_]*) +(?<Mode>[A-Za-z_]+[A-Za-z0-9_]*) +(?<Value>([A-Za-z0-9,./\\\\_]+)|(\"((\\\\\")|[^\"])+\")|(\\(((\\\\\\))|[^)])+\\)))((( +(?<Description>.+))?;)|( +(?<Description>.+))?)$");
            /* 匹配 using Namespace */
            UsingRegex = new Regex("^// *using +(?<Name>[A-Za-z_]+[A-Za-z0-9_]*(\\.[A-Za-z_]+[A-Za-z0-9_]*)*);?$");
            /* 匹配 import AssemblyName */
            ImportRegex = new Regex("^// *import +\"(?<Name>[A-Za-z_]+[A-Za-z0-9_]*(\\.[A-Za-z_]+[A-Za-z0-9_]*)*)\";?$");
        }

        /// <summary>
        /// 匹配命令验证器列表，命名空间引入列表，程序集引入列表。
        /// </summary>
        /// <param name="Code">代码原文</param>
        /// <param name="ImportsList">程序集引入列表</param>
        /// <param name="UsingsList">命名空间引入列表</param>
        /// <param name="ValidationsList">命令验证器列表</param>
        public static void GetValidations(ref string Code, List<string> ImportsList, List<string> UsingsList, List<CommandFieldVerifier> ValidationsList)
        {
            using (var CodeReader = new StringReader(Code))
            {
                Code = "";

                while (true)
                {
                    var LineCode = CodeReader.ReadLine();

                    if (LineCode == null)
                    {
                        break;
                    }

                    Match CodeMatch;

                    if ((CodeMatch = ImportRegex.Match(LineCode)).Success)
                    {
                        var AssemblyName = CodeMatch.Groups["Name"].Value;

                        if (!ImportsList.Contains(AssemblyName))
                        {
                            ImportsList.Add(AssemblyName);
                        }
                    }
                    else if ((CodeMatch = UsingRegex.Match(LineCode)).Success)
                    {
                        var Namespace = CodeMatch.Groups["Name"].Value;

                        if (!UsingsList.Contains(Namespace))
                        {
                            UsingsList.Add(Namespace);
                        }
                    }
                    else if ((CodeMatch = ValidationRegex.Match(LineCode)).Success)
                    {
                        var Value = CodeMatch.Groups["Value"].Value;

                        if ((Value.StartsWith("\"") && Value.EndsWith("\"")) || (Value.StartsWith("(") && Value.EndsWith(")")))
                        {
                            Value = Value.Substring(1, Value.Length - 2);
                        }

                        ValidationsList.Add(new CommandFieldVerifier(CodeMatch.Groups["Name"].Value, CodeMatch.Groups["Mode"].Value, Value, CodeMatch.Groups["Description"].Value));
                    }
                    else
                    {
                        Code = LineCode + CodeReader.ReadToEnd();
                    }
                }
            }
        }

        /// <summary>
        /// 处理命令
        /// </summary>
        /// <param name="Process">处理器</param>
        /// <param name="CommandInfo">命令信息</param>
        /// <param name="Writer">数据写入器</param>
        public abstract void Process(BaseProcess Process, CommandInfo CommandInfo, IDataWriter Writer);

        /// <summary>
        /// 处理命令
        /// </summary>
        /// <param name="Process">处理器</param>
        /// <param name="CommandInfo">命令信息</param>
        /// <param name="Callback">回掉函数</param>
        public abstract void Process(BaseProcess Process, CommandInfo CommandInfo, Action<IDataReader> Callback);

        /// <summary>
        /// 初始化命令
        /// </summary>
        /// <param name="CommandInfo"></param>
        public abstract void Initialization(CommandInfo CommandInfo);

        /// <summary>
        /// 获取用于缓存的参数对比信息
        /// </summary>
        /// <param name="Process">处理器</param>
        /// <param name="CommandInfo">命令信息</param>
        /// <returns>返回一个参数值集合</returns>
        public virtual object[] GetCacheParamsSign(BaseProcess Process, CommandInfo CommandInfo)
        {
            object[] Result = new object[CommandInfo.Params.Length];

            for (int i = 0; i < Result.Length; i++)
            {
                Result[i] = Process[CommandInfo.Params[i].Name];
            }

            return Result;
        }
    }
}